iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
DevOps

AWS ECS + Gitlab + Laravel + Terraform 從入門到摔坑系列 第 8

Day 8 了解 Container Instance & 定義 Task Definition

  • 分享至 

  • xImage
  •  

昨天我們建立了 ECS cluster 並且用 Auto Scaling Group 啟動 EC2 instance、向 ECS cluster 註冊為 Container Instance。今天我們來了解魔法作為 Container Instance 的 EC2 instance 有哪些必要的設定,然後建立 ECS Task Definition 來定義要做什麼工作。

Container Instance 的 Launch Template

要了解 Container Instance,就是看它 Launch Template 做了些什麼~我們到 EC2 的 launch template 找到 AWS 幫我們建立的 launch template(從 auto scaling group 點過去也行~),看它的 details:

https://ithelp.ithome.com.tw/upload/images/20230918/20160671qC3FJpC5Wz.png

第一個要注意的是 EC2 instance 啟動用的 AMI ID,它可不是一般的 Ubuntu 或者 Amazon Linux,它是 AWS 預先做好、調整好給 ECS 使用的 ECS-optimized AMI

https://ithelp.ithome.com.tw/upload/images/20230918/20160671VGscSkeZ9f.png

如果沒有自訂需求,直接用 ECS-optimized AMI 啟動 EC2 instance 來當 container instance 是最簡單的。如果有需要,AWS 也提供 ECS-optimized AMI 的 build script 可以依照需求自己做 AMI。

再來我們看 Advanced details,裡面的 IAM instance profile 跟 User data 是值得注意的部份:

https://ithelp.ithome.com.tw/upload/images/20230918/20160671NO7fHlXaJs.png

IAM instance profile 是把 IAM role 交給 EC2 instance 的東西,也就是 EC2 instance 會有 instance profile 擁有的 IAM role 的權限。通常用 AWS web console 建立的 instance profile 的名稱會跟它的 IAM role 名稱一樣,可以用 AWSCLI 指令 iam get-instance-profile 查詢一個 instance profile 有哪些 role:

$ aws iam get-instance-profile --instance-profile-name ecsInstanceRole
{
    "InstanceProfile": {
        "Path": "/",
        "InstanceProfileName": "ecsInstanceRole",
        "InstanceProfileId": "AIPAVS4C7DLN2OQO66UJK",
        "Arn": "arn:aws:iam::xxxxxxxxx:instance-profile/ecsInstanceRole",
        "CreateDate": "2023-07-09T09:28:21+00:00",
        "Roles": [
            {
                "Path": "/",
                "RoleName": "ecsInstanceRole",
                "RoleId": "AROAVS4C7DLNT5RP5YRAS",
                "Arn": "arn:aws:iam::xxxxxxxxx:role/ecsInstanceRole",
                "CreateDate": "2023-07-09T09:28:21+00:00",
                "AssumeRolePolicyDocument": {
                    "Version": "2008-10-17",
                    "Statement": [
                        {
                            "Sid": "",
                            "Effect": "Allow",
                            "Principal": {
                                "Service": "ec2.amazonaws.com"
                            },
                            "Action": "sts:AssumeRole"
                        }
                    ]
                }
            }
        ],
        "Tags": []
    }
}

launch template 指定的 instance profile 有 ecsInstanceRole role。進到 ecsInstanceRole 的頁面,可以看到它有一個 AWS 管理的 policy AmazonEC2ContainerServiceforEC2Role ,這是 EC2 instance 要當作 container instance 需要的權限。

user data 是讓 EC2 instance 自動做些事情的方法之一,在 EC2 instance 的 user data 寫 shell 指令可以讓這些指令在第一次啟動 instance 的時候執行 (ref)。launch template 指定的 user data 當然會帶給由它啟動的 EC2 instance。

#!/bin/bash 
echo ECS_CLUSTER=my-app >> /etc/ecs/ecs.config;

這段 shell script 是在 /etc/ecs/ecs.config 這個檔案加入 ECS_CLUSTER=my-app ,也就是告訴 ECS container agent 要加入 my-app 這個 ECS cluster。ECS container agent 是個執行在 container instance 裡的 container,它負責傳送目前正在執行的 task 及資源使用等資訊給 ECS,也會在收到 ECS 的 request 時啟動或停止 container。

建立 Task Definition

task definition 顧名思義是 task 的「定義」——這個 task 要用什麼 infrastructure 跑、需要多少 CPU 跟 Memory、有幾個 container、container 的設定諸如使用的 image、port mapping、volume 等等。

一個 task definition 會有多個版本(revision)。同一個 task definition 的多個版本組成的 group 稱為 task definition family。版本一旦建立就不能再修改,如果要修改 task definition 得要建立新版本(revision)。

每個 task 跟 service 都是依照一個 task definition 的某個版本來執行。task definition 與 task/service 的關係類似於電腦 program 與 process,或者物件導向程式設計中 class 與 object 的關係,就像模具跟成品。(筆者的另類比喻:前者是死的、後者是活的)

在 ECS 左邊選單選 Task definitions:

https://ithelp.ithome.com.tw/upload/images/20230918/20160671ni2N830e9Z.png

右上角 Create new task definition:

https://ithelp.ithome.com.tw/upload/images/20230918/20160671SpIX1bmfiz.png

一樣的,幫 task definition 取個名字~接著是 infrastructure 的設定:

https://ithelp.ithome.com.tw/upload/images/20230918/20160671o2viT91teV.png

Launch type 我們要用 EC2 instance 執行 container 所以勾 Amazon EC2 instances。OS 跟 Architecture 用 Linux 跟一般 x86_64 即可。

Network mode 選 bridge,這是在 Linux 上使用 Docker 內建 virtual network 的模式,也就是平常用 docker 開 container 的預設網路模式。後面我們會在 container definition 內指定 container 跟 host 之間的 port mapping,就像 docker run 裡的 -p

Task size 是指定要保留給這個 task 的 CPU 跟 memory,launch type 是 EC2 的時候這個欄位可填可不填,我們先簡單寫 1 vCPU 跟 0.5 GB 的 memory,跑 task 後依照實際使用量再微調到更適合的設定值即可。

最後是 Task role 及 Task execution role。Task role 類似 EC2 instance 的 IAM instance profile,它會提供 IAM role 給 container,讓 container 有權限 call AWS 的 API。Task execution role 則是給 container agent 的 IAM role。目前我們兩個都不會用到,先不設定。

接下來來到 container 的定義,我們會在這個區塊定義這個 task 要啟動的 container,一個 task 可以有多台定義各不相同的 container,我們設定一個 container:

https://ithelp.ithome.com.tw/upload/images/20230918/201606710TTqc6hq9x.png

設好 container 的名字。Image URI 填要用來建立 container 的 docker image 的 URI:[ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest (就是我們 push 到 ECR repository 裡的 image!)。

Essential container 是一個 task 中如果 fail 或 stop 會導致其他 container 也停止運作的 container(就是重要、如果沒了有其他 container 也無法正常提供服務的 container!),一個 task 至少要有一個 Essential container。這個 container 是 task definition 裡唯一的 container 所以選 Yes。

前面 network mode 提過 port mapping,它有點像 docker run-p ,讓 container 可以透過 host 的 port 收送 network traffic。我們指定 container 的 port、使用的 protocol、名稱以及 application 使用的 protocol。Laravel 是 web application,預設會開在 container 的 port 80、使用 TCP protocol,而 application protocol 是 HTTP。

Host port 先設 80 讓它 mapping 到 host 的 port 80,也就是連到 host 的 port 80 時會連到 container 的 port 80。這種直接指定 host port 的方式稱為 static port mapping。

後面這些 optional 設定基本不多設定。預設如果有勾 Use log collection,我們先把它取消,後面會用 terraform 加。(AWS 介面一直改…原本預設是沒有 Logging 的…=_=)

https://ithelp.ithome.com.tw/upload/images/20230918/20160671wmWr4ftFgC.png

目前架構

最後來看看這兩天加上 ECS cluster、auto scaling group 以及 task definition 的架構:

https://ithelp.ithome.com.tw/upload/images/20230918/20160671plf4Q5YJIe.png

auto scaling group 會在 public subnet 啟動 EC2 instance,這些 EC2 instance 擁有 ecsInstanceRole 的 IAM role,它們會向 ECS cluster 註冊為 container instance。此外我們定義了 task definition,裡面包含 task 以什麼作業系統與網路模式的 EC2 啟動、task 所需資源、使用 ECR 的 image 的 container 定義等等。


上一篇
Day 7 進入 ECS:建立 ECS Cluster
下一篇
Day 9 基本 ECS Service
系列文
AWS ECS + Gitlab + Laravel + Terraform 從入門到摔坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言